import { RouteComponentProps } from 'react-router-dom';
import { memo, useCallback, useContext, useEffect, useState } from 'react';
import { GlobalContext } from '../../router';

// 定义函数式组件Second的Props
interface SecondProps extends RouteComponentProps {
    content?: string;
}

// 使用箭头函数定义一个函数式组件
const Second = (props: SecondProps) => {
    // 使用hooks【useState】，返回一个 query，以及更新 query 的函数 setQuery。
    const [query, setQuery] = useState<string>('react');
    const [loading, setLoading] = useState<boolean>(true);
    // 模拟刷新
    const [count, setCount] = useState<number>(0);
    // 表示内容
    const [titleList, setTitleList] = useState<Array<string>>([]);

    // 使用hooks【useEffect】模拟生命周期
    // 如果useEffect第二个参数传入一个空数组的话，则useEffect只会在组件mount时执行。
    useEffect(() => {
        // 模拟【componentDidMount】
        console.log('【addEventListener】');
        window.addEventListener('resize', () => {}, false);
        // 模拟 【componentWillUnmount】
        return () => {
            console.log('【removeEventListener】');
            window.removeEventListener('resize', () => {}, false);
        };
    }, []);

    // 如果useEffect第二个参数不传入的话，则在组件每一次更新阶段，useEffect都会执行
    useEffect(() => {
        console.log(`【useEffect】第二个参数为空, query的值为${query}`);
    });

    // 如果useEffect第二个参数的数组内，传入了state，
    // 则useEffect会在mount时执行和state的值发生改变时执行
    useEffect(() => {
        console.log(`【useEffect】第二个参数为[query], query的值为${query}`);
        const url = 'http://blogapi.hellosu.top/v1/blog/getArticleList';
        // 调用接口获取列表
        fetch(url, {
            headers: { 'content-type': 'application/json' },
            method: 'POST',
            body: JSON.stringify({
                article_title: query,
            }),
        })
            .then(rsp => {
                rsp.json().then(data => {
                    const titleList = data.data.lists.map((item: any) => item.article_title);
                    setTitleList(titleList);
                    setLoading(false);
                });
            })
            .catch(() => {
                setTitleList(['Error']);
                setLoading(false);
            });
    }, [query, count]);

    // 做性能优化处理
    // useCallback返回的是一个 memoized（缓存）函数，
    // 在依赖不变的情况下, 多次定义的时候, 返回的值是相同的，
    // 他的实现原理是当使用一组参数初次调用函数时，会缓存参数和计算结果，
    // 当再次使用相同的参数调用该函数时，会直接返回相应的缓存结果。
    const currentQuery = useCallback(() => {
        return `当前query值: ${query}`;
    }, [query]);

    // 获取列表
    const content = titleList.map(title => {
        return <div key={title}>{title}</div>;
    });

    // 要显示内容
    const show = loading ? <div>Loading...</div> : content;

    return (
        <div>
            <h1>Second Page</h1>
            <h2>{count}</h2>
            {show}
            <button
                onClick={() => {
                    props.history.goBack();
                }}>
                pop
            </button>
            <button
                onClick={() => {
                    setLoading('python' !== query);
                    setQuery('python');
                }}>
                搜索python
            </button>
            <button
                onClick={() => {
                    setLoading('react' !== query);
                    setQuery('react');
                }}>
                搜索react
            </button>
            <SecondGlobalChild />
            <button onClick={() => setCount(count + 1)}>刷新</button>
            <SecondCallBackChild1 valueCall={currentQuery} />
            <SecondCallBackChild2 current={query} />
        </div>
    );
};

// 定义一个Second的子组件SecondGlobalChild，
// 通过【useContext】获取全局共享数据
const SecondGlobalChild = () => {
    // 使用hooks【useContext】获取全局共享数据
    const value = useContext(GlobalContext);
    return (
        <div>
            <h3 style={{ color: 'red' }}>全局数据: {value}</h3>
        </div>
    );
};

// const SecondCallBackChild = (props: { text: string }) => {
//     useEffect(() => {
//
//     }, [props.text]);
// };

// 使用memo包裹Second子组件，配合hooks【useCallback】进行性能优化
const SecondCallBackChild1 = memo((props: { valueCall: () => string }) => {
    console.log('【SecondCallBackChild1】触发render');
    return <div>{props.valueCall()}</div>;
});

// 普通Second子组件
const SecondCallBackChild2 = (props: { current: string }) => {
    console.log('【SecondCallBackChild2】触发render');
    return <div>{props.current}</div>;
};

export default Second;
